package com.hpsk.shopservice.model.config.controller;

import com.hpsk.annotations.ThreadAspectAnnotation;
import com.hpsk.common.RespResult;
import com.hpsk.common.RespUtils;
import com.hpsk.shopservice.model.config.service.TestAsyncService;
import com.hpsk.thread.ThreadLocalTestId;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.Future;

/**
 * @author huangwang2832511019
 */
@RestController
@Tag(name = "测试异步控制器")
@Slf4j
@RequestMapping("/testAsync")
@RequiredArgsConstructor(onConstructor_ = {@Autowired})
public class TestAsyncController {
    private final TestAsyncService testAsyncService;

    @GetMapping("/async")
    @Operation(summary = "异步方法")
    @ThreadAspectAnnotation
    public RespResult<String> async() {
        long start = System.currentTimeMillis();
        log.info("异步方法开始");
        String s = ThreadLocalTestId.get();
        log.info("线程值：{}", s);
        testAsyncService.asyncMethod(2);
        log.info("异步方法结束");
        long end = System.currentTimeMillis();
        log.info("异步方法总耗时：{} ms", end - start);
        return RespUtils.ok(String.format("耗时：%s ms", end - start));
    }

    @GetMapping("/asyncFuture/{param}")
    @Operation(summary = "异步方法返回值")
    @ThreadAspectAnnotation
    public RespResult<String> asyncFutureMethod(@PathVariable("param") String param) throws Exception {
        long start = System.currentTimeMillis();
        log.info("异步方法返回值开始");
        String s = ThreadLocalTestId.get();
        log.info("线程值：{}", s);
        Future<String> stringFuture = testAsyncService.asyncFutureMethod(param);
        String result = stringFuture.get();
        log.info("异步方法返回值：{}", result);
        log.info("异步方法返回值结束");
        long end = System.currentTimeMillis();
        log.info("异步方法返回值总耗时：{} ms", end - start);
        return RespUtils.ok(String.format("耗时：%s ms", end - start));
    }

    @GetMapping("sync")
    @Operation(summary = "同步方法")
    @ThreadAspectAnnotation
    public RespResult<String> testSync() {
        long start = System.currentTimeMillis();
        log.info("同步方法开始");
        String s = ThreadLocalTestId.get();
        log.info("线程值：{}", s);
        testAsyncService.syncMethod();
        log.info("同步方法结束");
        long end = System.currentTimeMillis();
        log.info("同步方法总耗时：{} ms", end - start);
        return RespUtils.ok(String.format("耗时：%s ms", end - start));
    }
}
